#pragma once
#ifndef _UTILITY_H
#define _UTILITY_H
#include "math\mathlib.h"
#include "math\matrix.h"
class GLFont;

long elapsed(void);

void gl_draw_axes(void);
void gl_draw_axes_tag(bool bOrthoProj,CSize Wnd_Size,GLFont *pFonts);

void CalcBillBoardTransform(const Vector3 &dir, const Vector3 &pos, float *m);

void DrawACross( CClientDC &ClientDC, CPoint & point, COLORREF cl,int size=2 );

class Arrow3D{
public:
	Arrow3D();
	Arrow3D(float _bar_radia);
	~Arrow3D(){		
		gluDeleteQuadric(pQuadric);	
	}
	void SetLengthAndRadia(float _lenRt, float _bar_radia);
	void SetFixHead(float _headlen, float _head_radia_ratio);
	void SetDoubleHead(bool bDblHd = false);
	void SetAdaptiveHead(float _head_lenRatio, float _head_radia_ratio );
	void gl_draw_3dArrow(Vector3 from,		Vector3 to);
	void gl_draw_3dArrow(Vector2 from,		Vector2 to);
	void gl_draw_3dCylinder(Vector3 from,	Vector3 to);
public:
	float	bar_radia, head_radia;
private:
	float	head_radiaRatio;
	float	vec_length, lenRt;
	float	head_len,	head_lenRatio;
	float	bar_len,	bar_lenRatio;
	

	Vector3 Ar_Vec, rot_axis;
	float	rot_angle;

	Vector3 axisZ;
	bool bDoubleHead;
private:
	float		baseRadia;
	GLUquadric *pQuadric ;
};

inline void CheckGlError()
{
	GLenum err =	glGetError();
	CString estr="";
	switch(err)
	{
	case GL_NO_ERROR:
		estr="GL_NO_ERROR";
		break;
	case GL_INVALID_ENUM:
		estr="GL_INVALID_ENUM";
		break;
	case GL_INVALID_VALUE:
		estr="GL_INVALID_VALUE";
		break;
	case GL_INVALID_OPERATION:
		estr="GL_INVALID_OPERATION";
		break;
	case GL_STACK_OVERFLOW:
		estr="GL_STACK_OVERFLOW";
		break;
	case GL_STACK_UNDERFLOW:
		estr="GL_STACK_UNDERFLOW";
		break;
	case GL_OUT_OF_MEMORY:
		estr="GL_OUT_OF_MEMORY";
		break;
	}
 	std::cout<<"GL error : "<<estr<<std::endl;
}

#endif